package com.ftl.autopunch.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ftl.autopunch.entity.SysUser;
import com.ftl.autopunch.mapper.SysUserMapper;
import com.ftl.autopunch.model.LoginFormModel;
import com.ftl.autopunch.model.UserTokenModel;
import com.ftl.autopunch.service.SysUserService;
import okhttp3.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    private String getSessionId(String origin) {
        Pattern pattern = Pattern.compile("SessionId=(.*?);");
        Matcher matcher = pattern.matcher(Objects.requireNonNull(origin));
        while (matcher.find()) {
            return matcher.group(1);
        }
        return "";
    }

    @Override
    public LoginFormModel getLoginForm() throws IOException {
        LoginFormModel loginFormModel = new LoginFormModel();
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        Request request = new Request.Builder()
                .url("http://xxtj.shufe-zj.edu.cn/Frame/Login.aspx")
                .method("GET", null)
                .build();
        Response response = client.newCall(request).execute();
        try {
            String respBody = Objects.requireNonNull(response.body()).string();
            String cookie = response.headers().get("Set-Cookie");
            String serverSessionId = getSessionId(cookie);
            loginFormModel.setServerSessionId(serverSessionId);
            Document loginDoc = Jsoup.parse(respBody);
            Element formTokenNode = loginDoc.select("input[name=FormToken]").first();
            loginFormModel.setFormToken(formTokenNode.attr("value"));
            Element buttonTokenNode = loginDoc.select("button[value=登录]").first();
            loginFormModel.setButtonToken(buttonTokenNode.attr("name"));
            return loginFormModel;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public UserTokenModel doLogin(LoginFormModel loginForm, SysUser sysUser) throws IOException {
        UserTokenModel userTokenModel = new UserTokenModel();
        userTokenModel.setUsername(sysUser.getUsername());
        userTokenModel.setServerSessionId(loginForm.getServerSessionId());
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "FormToken=" + loginForm.getFormToken()
                + "&Action=Save&Redirect=&LoginName=" + sysUser.getUsername() + "&Password=" + sysUser.getPassword()
                + "&" + loginForm.getButtonToken() + "=登录");
        Request request = new Request.Builder()
                .url("http://xxtj.shufe-zj.edu.cn/Frame/Login.aspx")
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .addHeader("Cookie", "ASP.NET_SessionId=" + loginForm.getServerSessionId() + ";")
                .build();
        Response response = client.newCall(request).execute();
        try {
            String respBody = Objects.requireNonNull(response.body()).string();
            if (respBody.contains("Frame.aspx")) {
                userTokenModel.setUserSessionId(getSessionId(response.headers().get("Set-Cookie")));
                return userTokenModel;
            } else if (respBody.contains("您输入的账号或密码无效")) {
                return new UserTokenModel();
            } else {
                throw new Exception("未知错误");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
